home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / libraries / newiff.lha / NewIFF / NewIFF39.lha / newiff39 / modules / screen.c < prev    next >
C/C++ Source or Header  |  1993-09-28  |  14KB  |  475 lines

  1. /* screen.c - 2.0 screen module for Display
  2.  * based on scdemo, oscandemo, looki
  3.  * 10/91 - added public screen support by checking user screen tags
  4.  *         for SA_PubScreen and setting screen public if found.
  5.  * 09/92 - added V39 BestFit call for modefallback, and usermodeid support
  6.  * 39.10 - cast Detail and Block pen to UBYTE, cast penarray value to UWORD
  7.  * 39.11 - Add NoCenter arg to clipit()
  8.  */
  9.  
  10. /*
  11. Copyright (c) 1989-1993 Commodore-Amiga, Inc.
  12.  
  13. Executables based on this information may be used in software
  14. for Commodore Amiga computers. All other rights reserved.
  15. This information is provided "as is"; no warranties are made.
  16. All use is at your own risk, and no liability or responsibility
  17. is assumed.
  18. */
  19.  
  20. #define INTUI_V36_NAMES_ONLY
  21.  
  22. #include "iffp/ilbmapp.h"
  23.  
  24. BOOL   VideoControlTags(struct ColorMap *,ULONG tags, ...);
  25.  
  26. extern struct Library *GfxBase;
  27. extern struct Library *IntuitionBase;
  28.  
  29. struct TextAttr SafeFont = { (UBYTE *) "topaz.font", 8, 0, 0, };
  30. UWORD  penarray[] = {(UWORD)~0};
  31.  
  32. /* default new window if none supplied in ilbm->nw */
  33. struct   NewWindow      defnw = {
  34.    0, 0,                                  /* LeftEdge and TopEdge */
  35.    0, 0,                                /* Width and Height */
  36.    (UBYTE)-1, (UBYTE)-1,                  /* DetailPen and BlockPen */
  37.    IDCMP_VANILLAKEY | IDCMP_MOUSEBUTTONS, /* IDCMP Flags with Flags below */
  38.    WFLG_BACKDROP | WFLG_BORDERLESS |
  39.    WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH |
  40.    WFLG_ACTIVATE | WFLG_RMBTRAP,
  41.    NULL, NULL,                            /* Gadget and Image pointers */
  42.    NULL,                                  /* Title string */
  43.    NULL,                                  /* Screen ptr null till opened */
  44.    NULL,                                  /* BitMap pointer */
  45.    50, 20,                                /* MinWidth and MinHeight */
  46.    0 , 0,                                 /* MaxWidth and MaxHeight */
  47.    CUSTOMSCREEN                           /* Type of window */
  48.    };
  49.  
  50.  
  51. /* opendisplay - passed ILBMInfo, dimensions, modeID
  52.  *
  53.  *    Attempts to open correct 2.0 modeID screen and window,
  54.  *    else an old 1.3 mode screen and window.
  55.  *
  56.  * Returns *window or NULL.
  57.  */
  58.  
  59. struct Window *opendisplay(struct ILBMInfo *ilbm,
  60.                SHORT wide, SHORT high, SHORT deep,
  61.                ULONG mode)
  62.     {
  63.     struct NewWindow newwin, *nw;
  64.  
  65.     closedisplay(ilbm);
  66.     if(ilbm->scr = openidscreen(ilbm, wide, high, deep, mode))
  67.     {
  68.     nw = &newwin;
  69.     if(ilbm->windef) *nw = *(ilbm->windef);
  70.     else *nw = *(&defnw);
  71.     nw->Screen    = ilbm->scr;
  72.  
  73.     D(bug("sizes: scr= %ld x %ld  passed= %ld x %ld\n",
  74.         ilbm->scr->Width,ilbm->scr->Height,wide,high)); 
  75.  
  76.     nw->Width    = wide;
  77.     nw->Height    = high;
  78.     if (!(ilbm->win = OpenWindow(nw)))
  79.         {
  80.         closedisplay(ilbm);
  81.         D(bug("Failed to open window."));
  82.         }
  83.     else
  84.         {
  85.         if(ilbm->win->Flags & WFLG_BACKDROP)
  86.         {
  87.         ShowTitle(ilbm->scr, FALSE);
  88.         ilbm->TBState = FALSE;
  89.         }
  90.         }
  91.     }
  92.  
  93.     if(ilbm->scr)    /* nulled out by closedisplay if OpenWindow failed */
  94.     {
  95.     ilbm->vp  = &ilbm->scr->ViewPort;
  96.     ilbm->srp = &ilbm->scr->RastPort;
  97.     ilbm->wrp = ilbm->win->RPort;
  98.     }
  99.     return(ilbm->win);
  100.     }
  101.  
  102.  
  103. /* Under 2.0, returns result of CloseScreen (TRUE for successful close)
  104.  * Under 1.3, always returns TRUE
  105.  */
  106. BOOL closedisplay(struct ILBMInfo *ilbm)
  107.     {
  108.     extern struct Library *IntuitionBase;
  109.     BOOL temp, result = TRUE;
  110.  
  111.     if(ilbm)
  112.     {
  113.     if(ilbm->scr)    ScreenToBack(ilbm->scr);
  114.         if(ilbm->win)    CloseWindow(ilbm->win), ilbm->win=NULL, ilbm->wrp=NULL;
  115.     if(ilbm->scr)
  116.         {
  117.         if(ilbm->scr->Flags & PUBLICSCREEN)
  118.         {
  119.         if(((struct Library *)IntuitionBase)->lib_Version >= 36)
  120.             PubScreenStatus(ilbm->scr, PSNF_PRIVATE);
  121.         }
  122.         temp = CloseScreen(ilbm->scr);
  123.         if(IntuitionBase->lib_Version >= 36)  result = temp;
  124.         if(result)
  125.         {
  126.         ilbm->scr = NULL;    
  127.             ilbm->vp  = NULL;
  128.             ilbm->srp = NULL;
  129.         }
  130.         }
  131.     }
  132.     return(result);
  133.     }
  134.  
  135.  
  136.  
  137. /* openidscreen - ILBMInfo, dimensions, modeID
  138.  *
  139.  *    Attempts to open correct 2.0 modeID screen with centered
  140.  *    overscan based on user's prefs,
  141.  *    else old 1.3 mode screen.
  142.  *
  143.  * If ilbm->stype includes CUSTOMBITMAP, ilbm->brbitmap will be
  144.  *       used as the screen's bitmap.
  145.  * If ilbm->stags is non-NULL, these tags will be added to the
  146.  *    end of the taglist.
  147.  *
  148.  * If ilbm->IFFPFlags IFFPF_USERMODE, use ilbm->usermodeid
  149.  * If ilbm->IFFPFlags IFFPF_BESTFIT, call modefallback()
  150.  *
  151.  * Returns *screen or NULL.
  152.  */
  153.  
  154. struct Screen *openidscreen(struct ILBMInfo *ilbm,
  155.                 SHORT wide, SHORT high, SHORT deep,
  156.                 ULONG mode)
  157.     {
  158.     struct NewScreen ns;            /* for old style OpenScreen */
  159.     DisplayInfoHandle displayhandle;
  160.     struct DimensionInfo dimensioninfo;
  161.     struct Rectangle spos, dclip, txto, stdo, maxo, uclip;  /* display rectangles */
  162.     struct Rectangle *uclipp;
  163.     struct Screen   *scr = NULL;
  164.     LONG   error, trynew;
  165.     ULONG  bitmaptag, passedtags;
  166.     BOOL   vctl;
  167.  
  168.     if(!ilbm)    return(0L);
  169.  
  170.     if(ilbm->IFFPFlags & IFFPF_USERMODE)    mode = ilbm->usermodeid;
  171.     if(ilbm->IFFPFlags & IFFPF_BESTFIT)
  172.     {
  173.     mode = modefallback(mode,wide,high,deep);
  174.     }
  175.  
  176.     if (trynew = ((((struct Library *)GfxBase)->lib_Version >= 36)&&
  177.           (((struct Library *)IntuitionBase)->lib_Version >= 36)))
  178.     {
  179.         /* if >= v36, see if mode is available */
  180.     if(error = ModeNotAvailable(mode))
  181.         {
  182.         D(bug("Mode $%08lx not available, error=%ld:\n",mode,error));
  183.         /* if not available, try fall back mode */
  184.         mode = modefallback(mode,wide,high,deep);
  185.         error = ModeNotAvailable(mode);
  186.  
  187.         D(bug("$%08lx ModeNotAvailable=%ld:\n",mode,error));
  188.         }
  189.  
  190.  
  191.     if(!error)    /* mode is available - how about depth ? */
  192.         {
  193.             if(displayhandle=FindDisplayInfo(mode))
  194.         {
  195.                 if(GetDisplayInfoData(displayhandle,(UBYTE *) &dimensioninfo,
  196.                 sizeof(struct DimensionInfo),DTAG_DIMS,NULL))
  197.             {
  198.             if(dimensioninfo.MaxDepth < deep)
  199.             {
  200.             message("%s: %ld %s\n",
  201.                 ilbm->ParseInfo.filename,
  202.                 ilbm->Bmhd.nPlanes,SI(MSG_ILBM_TOODEEP));
  203.             deep = dimensioninfo.MaxDepth;
  204.             }
  205.             }
  206.         }
  207.         }
  208.  
  209.     if(error) trynew = FALSE;
  210.     else trynew=((QueryOverscan(mode,&txto,OSCAN_TEXT))&&
  211.             (QueryOverscan(mode,&stdo,OSCAN_STANDARD))&&
  212.                 (QueryOverscan(mode,&maxo,OSCAN_MAX)));
  213.     }
  214.  
  215.     D(bug("\nILBM: w=%ld, h=%ld, d=%ld, mode=0x%08lx\n",
  216.         wide,high,deep,mode));    
  217.     D(bug("OPEN: %s.\n",
  218.         trynew    ? "Is >= 2.0 and mode available, trying OpenScreenTags"
  219.         : "Not 2.0, doing old OpenScreen"));
  220.  
  221.     if(trynew)
  222.     {
  223.     /* If user clip type specified and available, use it */
  224.     if(ilbm->Video) ilbm->ucliptype = OSCAN_VIDEO;
  225.     if((ilbm->ucliptype)&&(QueryOverscan(mode,&uclip,ilbm->ucliptype)))
  226.         uclipp = &uclip;
  227.     else uclipp = NULL;
  228.  
  229.     clipit(wide,high,&spos,&dclip,&txto,&stdo,&maxo,uclipp,
  230.         ilbm->IFFPFlags & IFFPF_NOCENTER ? TRUE : FALSE);
  231.  
  232.     D(bug("Using dclip  %ld,%ld  to  %ld,%ld... width=%ld height=%ld\n",
  233.             dclip.MinX,dclip.MinY,dclip.MaxX,dclip.MaxY,
  234.             dclip.MaxX-dclip.MinX+1,dclip.MaxY-dclip.MinY+1));
  235.     D(bug("spos->minx = %ld, spos->miny = %ld\n",spos.MinX,spos.MinY));
  236.     D(bug("DEBUG: About to attempt OpenScreenTags\n"));
  237.  
  238.     bitmaptag = ((ilbm->brbitmap)&&(ilbm->stype & CUSTOMBITMAP)) ?
  239.         SA_BitMap : TAG_IGNORE;
  240.     passedtags = ilbm->stags ? TAG_MORE : TAG_IGNORE;
  241.  
  242.     scr=(struct Screen *)OpenScreenTags((struct NewScreen *)NULL,
  243.         SA_DisplayID,    mode,
  244.         SA_Type,    ilbm->stype,
  245.         SA_Behind,    TRUE,
  246.         SA_Top,        spos.MinY,
  247.         SA_Left,    spos.MinX,
  248.         SA_Width,    wide,
  249.         SA_Height,    high,
  250.         SA_Depth,    deep,
  251.         SA_DClip,    &dclip,
  252.         SA_AutoScroll,    ilbm->Autoscroll ? TRUE : FALSE,
  253.         SA_Title,    ilbm->stitle,
  254.         SA_Font,    &SafeFont,
  255.         SA_Pens,    penarray,
  256.         SA_ErrorCode,    &error,
  257.         bitmaptag,    ilbm->brbitmap,
  258.         passedtags,    ilbm->stags,
  259.         TAG_DONE
  260.         );
  261.  
  262.         D(bug("DEBUG: OpenScreenTags scr at 0x%lx\n",scr));
  263.  
  264.         if(scr)
  265.         {
  266.         /* If caller specified a public screen, open for business */
  267.         if(scr->Flags & PUBLICSCREEN)
  268.             {
  269.             if(((struct Library *)IntuitionBase)->lib_Version >= 36)
  270.                 PubScreenStatus(scr,NULL);
  271.             }
  272.         if(ilbm->Notransb)
  273.             {
  274.             vctl=VideoControlTags(scr->ViewPort.ColorMap,
  275.                 VTAG_BORDERNOTRANS_SET, TRUE,
  276.                 TAG_DONE);
  277.  
  278.     D(bug("VideoControl to set bordernotrans, error = %ld\n",vctl));
  279.  
  280.             MakeScreen(scr);
  281.             RethinkDisplay();
  282.             }
  283.         }
  284.         else message("%s\n",openScreenErr(error));
  285.         }
  286.  
  287.     if(!scr)
  288.     {
  289.     /* ns initialization for 1.3 old style OpenScreen only
  290.          */
  291.     ns.LeftEdge = ns.TopEdge = 0;   
  292.     ns.Width     =    wide;
  293.     ns.Height     =    high;
  294.     ns.Depth    =    deep;
  295.     ns.ViewModes    =     modefallback(mode,wide,high,deep);
  296.     ns.DetailPen    =    0;
  297.     ns.BlockPen    =    1;
  298.     ns.Gadgets    =    NULL;
  299.     ns.CustomBitMap    =    ((ilbm->brbitmap)&&(ilbm->stype & CUSTOMBITMAP))
  300.                     ? ilbm->brbitmap : NULL;
  301.     ns.Font        =    &SafeFont;
  302.     ns.DefaultTitle =     ilbm->stitle;
  303.     ns.Type        =    ilbm->stype & 0x01FF;  /* allow only 1.3 types */
  304.  
  305.     scr=(struct Screen *)OpenScreen(&ns);
  306.  
  307.     D(bug("DEBUG: ns.ViewModes=0x%lx, vp->Modes=0x%lx\n",
  308.                  ns.ViewModes,scr->ViewPort.Modes));
  309.     D(bug("DEBUG: non-extended scr at 0x%lx (0=failure)\n",scr));
  310.     }
  311.     return(scr);
  312.     }
  313.  
  314.  
  315. /*
  316.  * modefallback - passed a mode id, attempts to provide a
  317.  *                suitable old mode to use instead
  318.  */
  319.  
  320. /* for old 1.3 screens */
  321. #define MODE_ID_MASK (LACE|HIRES|HAM|EXTRA_HALFBRITE)
  322.  
  323. ULONG modefallback(ULONG oldmode, SHORT wide, SHORT high, SHORT deep)
  324. {
  325.     ULONG newmode, bestmode;
  326.     struct TagItem tags[6];
  327.  
  328.     if(GfxBase->lib_Version >= 39)
  329.     {
  330.     tags[0].ti_Tag = BIDTAG_DIPFMustHave;
  331.     tags[0].ti_Data = (oldmode & HAM ? DIPF_IS_HAM : 0);
  332.     tags[0].ti_Data |= (oldmode & EXTRA_HALFBRITE ? DIPF_IS_EXTRAHALFBRITE : 0);
  333.     tags[1].ti_Tag = BIDTAG_NominalWidth;
  334.     tags[1].ti_Data = wide; //bmhd->XAspect; //wide;
  335.     tags[2].ti_Tag = BIDTAG_NominalHeight;
  336.     tags[2].ti_Data = high; //bmhd->YAspectHeight; //high;
  337.     tags[3].ti_Tag = BIDTAG_Depth;
  338.     tags[3].ti_Data = deep;
  339.     tags[4].ti_Tag = BIDTAG_SourceID;
  340.     tags[4].ti_Data = (FindDisplayInfo(oldmode) ? oldmode : (oldmode & (~(MONITOR_ID_MASK | SPRITES|GENLOCK_AUDIO|GENLOCK_VIDEO|VP_HIDE))));
  341.     tags[5].ti_Tag = TAG_DONE;
  342.  
  343.     if((bestmode = BestModeIDA(tags)) != INVALID_ID)
  344.         {
  345.         newmode = bestmode;
  346.         }
  347.     D(bug("Best fit ID = 0x%lx\n", newmode));
  348.     }
  349.     else
  350.     {
  351.         newmode = oldmode & MODE_ID_MASK;
  352.         D(bug("Falling back to 0x%08lx instead of 0x%08lx\n",newmode,oldmode));
  353.     }    
  354.     return(newmode);
  355. }
  356.  
  357.  
  358. /*
  359.  * clipit - passed width and height of a display, and the text, std, and
  360.  *          max overscan rectangles for the mode, clipit fills in the
  361.  *          spos (screen pos) and dclip rectangles to use in centering.
  362.  *          Centered around smallest containing user-editable oscan pref,
  363.  *          with dclip confined to legal maxoscan limits.
  364.  *          Screens which center such that their top is below text
  365.  *          oscan top, will be moved up.
  366.  *          If a non-null uclip is passed, that clip is used instead.
  367.  *
  368.  * 39.11 - Added NoCenter BOOl arg. If set, image top-left will be
  369.  *         positioned at displayclip top-left (i.e. not centered)
  370.  */
  371. void clipit(SHORT wide, SHORT high,
  372.         struct Rectangle *spos, struct Rectangle *dclip,
  373.         struct Rectangle *txto, struct Rectangle *stdo,
  374.         struct Rectangle *maxo, struct Rectangle *uclip,
  375.         BOOL NoCenter)
  376. {
  377. struct  Rectangle *besto;
  378. SHORT    minx, maxx, miny, maxy;
  379. SHORT    txtw, txth, stdw, stdh, maxw, maxh, bestw, besth;
  380.  
  381.     /* get the txt, std and max widths and heights */
  382.     txtw = txto->MaxX - txto->MinX + 1;
  383.     txth = txto->MaxY - txto->MinY + 1;
  384.     stdw = stdo->MaxX - stdo->MinX + 1;
  385.     stdh = stdo->MaxY - stdo->MinY + 1;
  386.     maxw = maxo->MaxX - maxo->MinX + 1;
  387.     maxh = maxo->MaxY - maxo->MinY + 1;
  388.  
  389.     if((wide <= txtw)&&(high <= txth))
  390.     {
  391.     besto = txto;
  392.     bestw = txtw;
  393.     besth = txth;
  394.  
  395.     D(bug("Best clip to center around is txto\n"));
  396.     }
  397.     else
  398.     {
  399.     besto = stdo;
  400.     bestw = stdw;
  401.     besth = stdh;
  402.  
  403.     D(bug("Best clip to center around is stdo\n"));
  404.     }
  405.  
  406.     D(bug("TXTO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  stdw=%ld stdh=%ld\n",
  407.         txto->MinX,txto->MinY,txto->MaxX,txto->MaxY,txtw,txth));
  408.     D(bug("STDO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  stdw=%ld stdh=%ld\n",
  409.         stdo->MinX,stdo->MinY,stdo->MaxX,stdo->MaxY,stdw,stdh));
  410.     D(bug("MAXO: mnx=%ld mny=%ld mxx=%ld mxy=%ld  maxw=%ld maxh=%ld\n",
  411.         maxo->MinX,maxo->MinY,maxo->MaxX,maxo->MaxY,maxw,maxh));
  412.  
  413.     if(uclip)
  414.     {
  415.     *dclip = *uclip;
  416.         spos->MinX = uclip->MinX;
  417.     spos->MinY = uclip->MinY;
  418.  
  419.     D(bug("UCLIP: mnx=%ld mny=%ld maxx=%ld maxy=%ld\n",
  420.             dclip->MinX,dclip->MinY,dclip->MaxX,dclip->MaxY));
  421.     }
  422.     else
  423.     {
  424.     /* CENTER the screen based on best oscan prefs
  425.      * but confine dclip within max oscan limits
  426.      *
  427.      * FIX MinX first */
  428.     spos->MinX = minx = besto->MinX - ((wide - bestw) >> 1);
  429.     maxx = wide + minx - 1;
  430.     if(maxx > maxo->MaxX)  maxx = maxo->MaxX;    /* too right */
  431.     if(minx < maxo->MinX)
  432.         {
  433.         minx = maxo->MinX;    /* too left  */
  434.         /* if we want left edge of screen not clipped */
  435.         if(NoCenter)    spos->MinX = minx;
  436.         }
  437.  
  438.     D(bug("DCLIP: minx adjust from %ld to %ld\n",spos->MinX,minx));
  439.  
  440.     /* FIX MinY */
  441.     spos->MinY = miny = besto->MinY - ((high - besth) >> 1);
  442.     /* if lower than top of txto, move up */
  443.     spos->MinY = miny = MIN(spos->MinY,txto->MinY);
  444.     maxy = high + miny - 1;
  445.     if(maxy > maxo->MaxY)  maxy = maxo->MaxY;    /* too down  */
  446.     if(miny < maxo->MinY)
  447.         {
  448.         miny = maxo->MinY;    /* too up    */
  449.         /* if we want top of screen not clipped */
  450.         if(NoCenter)    spos->MinY = miny;
  451.         }
  452.     D(bug("DCLIP: miny adjust from %ld to %ld\n",spos->MinY,miny));
  453.  
  454.     /* SET up dclip */
  455.     dclip->MinX = minx;
  456.     dclip->MinY = miny;
  457.     dclip->MaxX = maxx;
  458.     dclip->MaxY = maxy;
  459.  
  460.     D(bug("CENTER: mnx=%ld mny=%ld maxx=%ld maxy=%ld\n",
  461.             dclip->MinX,dclip->MinY,dclip->MaxX,dclip->MaxY));
  462.     }
  463. }
  464.  
  465. /*----------------------------------------------------------------------*/
  466.  
  467. BOOL VideoControlTags(struct ColorMap *cm, ULONG tags, ...)
  468.     {
  469.     return (VideoControl(cm, (struct TagItem *)&tags));
  470.     }
  471.  
  472.  
  473. /*----------------------------------------------------------------------*/
  474.  
  475.